/**
 * 
 */
package cc.w3d.jawos.apps.artiks.client.components;

import java.util.List;

import cc.w3d.jawos.apps.artiks.client.Artiks;
import cc.w3d.jawos.apps.artiks.client.rpc.ArtiksAsyncCallback;
import cc.w3d.jawos.apps.artiks.client.widgets.IconToolBarButton;
import cc.w3d.jawos.apps.artiks.client.widgets.ToolBar;
import cc.w3d.jawos.apps.artiks.client.widgets.ToolBarButton;
import cc.w3d.jawos.apps.artiks.manager.client.beans.ResourceItem;
import cc.w3d.jawos.apps.artiks.manager.client.beans.ResourceType;

import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;

public class TreePanel extends Composite implements ClickHandler, RequiresResize, HasSelectionHandlers<ResourceTreeItem>
{
	private static class ResourceSelectionEvent extends SelectionEvent<ResourceTreeItem>
	{
		ResourceSelectionEvent(ResourceTreeItem selectedItem)
			{super(selectedItem);}
		ResourceSelectionEvent(TreeItem selectedItem)
			{super((ResourceTreeItem)selectedItem);}
	}

	final ToolBarButton plusArticle = new IconToolBarButton(Artiks.icons.new_document(), this);
	final ToolBarButton plusCarpeta = new IconToolBarButton(Artiks.icons.new_folder(), this);
	final ToolBarButton minus       = new IconToolBarButton(Artiks.icons.bin(), this);

	final Tree tree = new Tree();
	final ScrollPanel scrollPanel = new ScrollPanel(tree);
	final ResourceTreeItem root = new ResourceTreeItem(null);

	public TreePanel()
	{
		tree.addItem(root);

		tree.addOpenHandler(new OpenHandler<TreeItem>()
		{
			public void onOpen(OpenEvent<TreeItem> event)
			{
				final ResourceTreeItem selectedTreeItem = (ResourceTreeItem)event.getTarget();
				selectedTreeItem.removeItems();

				Artiks.service.getChilds(selectedTreeItem.getId(), new ArtiksAsyncCallback<List<ResourceItem>>()
				{
					@Override
					public void onFinish(List<ResourceItem> result)
					{
						onResize();
						for (ResourceItem item : result)
							selectedTreeItem.addItem(new ResourceTreeItem(item));
					}
				});
			}
		});

		VerticalPanel treePanel = new VerticalPanel();

		ToolBar toolBar = new ToolBar();

		plusArticle.setTitle("Afegir nou Article");
		plusCarpeta.setTitle("Afegir nova Carpeta");
		minus.setTitle("Eliminar l'element seleccionat");

		toolBar.addChild(plusArticle);
		toolBar.addChild(plusCarpeta);

		toolBar.addRightChild(minus);

		treePanel.add(toolBar);
		scrollPanel.setAlwaysShowScrollBars(false);
		treePanel.add(scrollPanel);
		scrollPanel.setWidth("100%");
		treePanel.setWidth("100%");


		tree.addBlurHandler(new BlurHandler()
			{public void onBlur(BlurEvent arg0) {fixButtonStates();}});

		tree.addSelectionHandler(new SelectionHandler<TreeItem>()
			{public void onSelection(SelectionEvent<TreeItem> arg0) {fixButtonStates();}});

		plusArticle.setEnabled(false);
		plusCarpeta.setEnabled(false);
		minus.setEnabled(false);

		initWidget(treePanel);
	}

	private void fixButtonStates()
	{
		ResourceTreeItem treeItem = (ResourceTreeItem)tree.getSelectedItem();

		plusArticle.setEnabled(treeItem != null && treeItem.isFolder());
		plusCarpeta.setEnabled(treeItem != null && treeItem.isFolder());
		minus.setEnabled(treeItem != null && !treeItem.isRoot());
	}

	public void onClick(ClickEvent event)
	{
		final ResourceTreeItem selectedTreeItem = (ResourceTreeItem)tree.getSelectedItem();

		ImageResource icon = ((IconToolBarButton)event.getSource()).getIcon();

		if(icon == Artiks.icons.bin())
		{
			if(Window.confirm("Està segur que vol eliminar '" + selectedTreeItem.getUserObject().name + "'"))
				Artiks.service.removeItem(selectedTreeItem.getId(), new ArtiksAsyncCallback<Void>() {

					@Override
					public void onFinish(Void result)
					{
						int index = selectedTreeItem.getParentItem().getChildIndex(selectedTreeItem);
						int nextIndex = -1;
						TreeItem next = selectedTreeItem.getParentItem();

						if(index == selectedTreeItem.getParentItem().getChildCount() -1)
							nextIndex = index-1;
						else
							nextIndex = index + 1;

						if(nextIndex != -1)
							next = next.getChild(nextIndex);

						selectedTreeItem.remove();
						tree.setSelectedItem(next, true);
						fixButtonStates();
					}
				});
		}
		else
		{
			boolean isFolder = icon == Artiks.icons.new_folder();

			String name = Window.prompt(
				"Introdueix un nom identificatiu per a" + (isFolder ? " la nova carpeta" : "l nou article"),
				"Nom " + (isFolder ? "Carpeta" : "Arxiu"));

			Artiks.service.addChild(selectedTreeItem.getId(), isFolder ? ResourceType.FOLDER : ResourceType.ARTICLE, name, new ArtiksAsyncCallback<ResourceItem>()
			{
				@Override
				public void onFinish(ResourceItem result)
					{selectedTreeItem.addItem(new ResourceTreeItem(result));}
			});
		}
		onResize();
	}

	private DockLayoutPanel parentPanel;

	public void onResize()
	{
		String h = (this.getParent().getOffsetHeight() - 18) + "px";
		String w = (parentPanel.getWidgetContainerElement(this).getOffsetWidth()) + "px";

		this.scrollPanel.setHeight(h);
		this.setHeight(h);
		this.setWidth(w);
		this.scrollPanel.setWidth(w);
	}

	public void onLoad()
	{
		super.onLoad();
		parentPanel = (DockLayoutPanel)this.getParent();

		DOM.setElementAttribute(getElement(), "style", DOM.getElementAttribute(getElement(), "style") + "background-color:#eeeeff;");
	}

	public void unfoldRoot()
		{tree.getItem(0).setState(true, true);}

	public HandlerRegistration addSelectionHandler(final SelectionHandler<ResourceTreeItem> handler)
	{
		return tree.addSelectionHandler(new SelectionHandler<TreeItem>()
		{
			public void onSelection(SelectionEvent<TreeItem> event)
			{
				SelectionEvent<ResourceTreeItem> e = new ResourceSelectionEvent(event.getSelectedItem());
				handler.onSelection(e);
			}
		});
	}
}